﻿using System;
using System.Collections.Generic;
using System.Security.Cryptography;
using Microsoft.Win32;

namespace SlideShowDFG2
{
    public class RegistryHelper
    {
        const string REGISTRY_KEY = @"Software\zmb\SlideShowDFG2";
        const int REQUIRED_VALUES = 17;
        readonly Dictionary<string, object> _defaults;

        public RegistryHelper()
        {
            _defaults = new Dictionary<string, object>();

            _defaults.Add("ResizeOption", 0);
            _defaults.Add("ResizeSeed", 640);
            _defaults.Add("WatermarkText", string.Empty);
            _defaults.Add("EnableWatermark", false);
            _defaults.Add("CreateThumbnail", false);
            _defaults.Add("FtpHost", string.Empty);
            _defaults.Add("FtpUserName", string.Empty);
            _defaults.Add("FtpPassword", string.Empty);
            _defaults.Add("FtpSaveDir", string.Empty);
            _defaults.Add("FtpDataFile", string.Empty);
            _defaults.Add("FtpPort", 21);
            _defaults.Add("FtpPreviewImage", false);
            _defaults.Add("FtpRememberConnection", false);
            _defaults.Add("FFmpegExe", string.Empty);
            _defaults.Add("VideoSize", "320x420");
            _defaults.Add("VideoBitrate", "934");
        }

        public void SetDefaults()
        {
            using (RegistryKey key = GetKey())
            {
                foreach (KeyValuePair<string, object> setting in _defaults)
                {
                    key.SetValue(setting.Key, setting.Value);
                }
            }
        }

        public bool AllKeysAvailable()
        {
            using (RegistryKey key = GetKey())
            {
                if (key.ValueCount != REQUIRED_VALUES) return false;
                else return true;
            }
        }

        private RegistryKey GetKey()
        {
            return Registry.CurrentUser.CreateSubKey(REGISTRY_KEY);
        }
        
        public int ResizeOption
        {
            get
            {
                using (RegistryKey key = GetKey())
                {
                    return (int)key.GetValue("ResizeOption", _defaults["ResizeOption"], RegistryValueOptions.None);
                }
            }
            set
            {
                using (RegistryKey key = GetKey())
                {
                    key.SetValue("ResizeOption", value);
                }
            }
        }
        
        public int ResizeSeed
        {
            get
            {
                using (RegistryKey key = GetKey())
                {
                    return (int)key.GetValue("ResizeSeed", _defaults, RegistryValueOptions.None);
                }
            }
            set
            {
                using (RegistryKey key = GetKey())
                {
                    key.SetValue("ResizeSeed", value);
                }
            }
        }
        
        public string WatermarkText
        {
            get
            {
                using (RegistryKey key = GetKey())
                {
                    return (string)key.GetValue("WatermarkText", _defaults["WatermarkText"], RegistryValueOptions.None);
                }
            }
            set
            {
                using (RegistryKey key = GetKey())
                {
                    key.SetValue("WatermarkText", value);
                }
            }
        }
        
        public bool EnableWatermark
        {
            get
            {
                using (RegistryKey key = GetKey())
                {
                    return Convert.ToBoolean(key.GetValue("EnableWatermark", _defaults["EnableWatermark"], RegistryValueOptions.None));
                }
            }
            set
            {
                using (RegistryKey key = GetKey())
                {
                    key.SetValue("EnableWatermark", value);
                }
            }
        }
        
        public bool CreateThumbnail
        {
            get
            {
                using (RegistryKey key = GetKey())
                {
                    return Convert.ToBoolean(key.GetValue("CreateThumbnail", _defaults["CreateThumbnail"], RegistryValueOptions.None));
                }
            }
            set
            {
                using (RegistryKey key = GetKey())
                {
                    key.SetValue("CreateThumbnail", value);
                }
            }
        }
        
        public string FtpHost
        {
            get
            {
                using (RegistryKey key = GetKey())
                {
                    return (string)key.GetValue("FtpHost", _defaults["FtpHost"], RegistryValueOptions.None);
                }
            }
            set
            {
                using (RegistryKey key = GetKey())
                {
                    key.SetValue("FtpHost", value);
                }
            }
        }
        
        public string FtpUserName
        {
            get
            {
                using (RegistryKey key = GetKey())
                {
                    return (string)key.GetValue("FtpUserName", _defaults["FtpUserName"], RegistryValueOptions.None);
                }
            }
            set
            {
                using (RegistryKey key = GetKey())
                {
                    key.SetValue("FtpUserName", value);
                }
            }
        }
        
        public string FtpPassword
        {
            get
            {
                using (RegistryKey key = GetKey())
                {
                    return CryptographyHelper.DecryptString((byte[])key.GetValue("FtpPassword"));
                }
            }
            set
            {
                using (RegistryKey key = GetKey())
                {
                    key.SetValue("FtpPassword", CryptographyHelper.EncryptString(value));
                }
            }
        }
        
        public string FtpSaveDir
        {
            get
            {
                using (RegistryKey key = GetKey())
                {
                    return (string)key.GetValue("FtpSaveDir", _defaults["FtpSaveDir"], RegistryValueOptions.None);
                }
            }
            set
            {
                using (RegistryKey key = GetKey())
                {
                    key.SetValue("FtpSaveDir", value);
                }
            }
        }
        
        public string FtpDataFile
        {
            get
            {
                using (RegistryKey key = GetKey())
                {
                    return (string)key.GetValue("FtpDataFile", _defaults["FtpDataFile"], RegistryValueOptions.None);
                }
            }
            set
            {
                using (RegistryKey key = GetKey())
                {
                    key.SetValue("FtpDataFile", value);
                }
            }
        }
        
        public int FtpPort
        {
            get
            {
                using (RegistryKey key = GetKey())
                {
                    return (int)key.GetValue("FtpPort", _defaults["FtpPort"], RegistryValueOptions.None);
                }
            }
            set
            {
                using (RegistryKey key = GetKey())
                {
                    key.SetValue("FtpPort", value);
                }
            }
        }
        
        public bool FtpPreviewImage
        {
            get
            {
                using (RegistryKey key = GetKey())
                {
                    return Convert.ToBoolean(key.GetValue("FtpPreviewImage", _defaults["FtpPreviewImage"], RegistryValueOptions.None));
                }
            }
            set
            {
                using (RegistryKey key = GetKey())
                {
                    key.SetValue("FtpImagePreview", value);
                }
            }
        }

        public bool FtpRememberConnection
        {
            get
            {
                using (RegistryKey key = GetKey())
                {
                    return Convert.ToBoolean(key.GetValue("FtpRememberConnection", _defaults["FtpRememberConnection"], RegistryValueOptions.None));
                }
            }
            set
            {
                using (RegistryKey key = GetKey())
                {
                    key.SetValue("FtpRememberConnection", value);
                }
            }
        }

        public string FFmpegExe
        {
            get
            {
                using (RegistryKey key = GetKey())
                {
                    return (string)key.GetValue("FFmpegExe", _defaults["FFmpegExe"], RegistryValueOptions.None);
                }
            }
            set
            {
                using (RegistryKey key = GetKey())
                {
                    key.SetValue("FFmpegExe", value);
                }
            }
        }

        public string VideoSize
        {
            get
            {
                using (RegistryKey key = GetKey())
                {
                    return (string)key.GetValue("VideoSize", _defaults["VideoSize"], RegistryValueOptions.None);
                }
            }
            set
            {
                using (RegistryKey key = GetKey())
                {
                    key.SetValue("VideoSize", value);
                }
            }
        }

        public string VideoBitrate
        {
            get
            {
                using (RegistryKey key = GetKey())
                {
                    return (string)key.GetValue("VideoBitrate", _defaults["VideoBitrate"], RegistryValueOptions.None);
                }
            }
            set
            {
                using (RegistryKey key = GetKey())
                {
                    key.SetValue("VideoBitrate", value);
                }
            }
        }
        
        public byte[] Entropy
        {
            get
            {
                using (RegistryKey key = GetKey())
                {
                    byte[] entropy = (byte[])key.GetValue("Entropy");
                    if (entropy == null)
                    {
                        entropy = new byte[16];
                        new RNGCryptoServiceProvider().GetBytes(entropy);
                        key.SetValue("Entropy", entropy);
                    }
                    return entropy;
                }
            }
        }
    }
}
